﻿using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Model.Config;
using Model.Entity;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using TemplateInterfaceService;

namespace TemplateService
{
    /// <summary>
    /// JWT服务
    /// </summary>
    public class JwtService : IJwtService
    {
        private readonly JWTTokenOptions _JWTTokenOptions;//JWT令牌配置

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="jwtTokenOptions"></param>
        public JwtService(IOptionsMonitor<JWTTokenOptions> jwtTokenOptions)
        {
            _JWTTokenOptions = jwtTokenOptions.CurrentValue;
        }

        /// <summary>
        /// 获取JWT令牌
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public async Task<string> GetJwtToken(Users user) 
        {
            var result = await Task.Run(() =>
            {
                //身份验证成功 步骤一：生成用户的Claims（无需消息传递也可不写）
                var claims = new List<Claim>
                {
                    new Claim("id", user.UserId.ToString()),
                    new Claim("username", user.Username),
                    new Claim("realName", user.RealName)                                      
                };

                //步骤二：生成加密key:
                //Nuget引入：Microsoft.IdentityModel.Tokens;
                SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_JWTTokenOptions.SecuritKey));

                //步骤三：根据加密key生成一个票据
                SigningCredentials creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

                //步骤四：生成JWT返回的Token
                //Nuget引入：System.IdentityModel.Tokens.Jwt;
                JwtSecurityToken jwtToken = new JwtSecurityToken(
                    issuer: _JWTTokenOptions.Issuer,//发送者
                    audience: _JWTTokenOptions.Audience,//接收者
                    claims: claims,//添加Claims
                    expires: DateTime.Now.AddMinutes(10),//过期时间
                    notBefore: null,//生效时间
                    signingCredentials: creds//签名
                );
                string token = new JwtSecurityTokenHandler().WriteToken(jwtToken);
                return token;
            });

            return result;
        }
    }
}
